package lrscp.lib.tcp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import lrscp.lib.Common;
import lrscp.lib.Log;

public abstract class TcpServer implements TcpSocket {
    private int mPort;
    ServerSocket server = null;
    private Socket s = null;
    boolean exit = false;

    public TcpServer(int port) {
        mPort = port;
        thd.start();
    }

    Thread thd = new Thread(new Runnable() {
        public void run() {
            while (!exit) {
                try {
                    server = new ServerSocket(mPort);
                    s = server.accept();
                    s.setKeepAlive(true);
                    Log.i("Get a client");
                    handleStream(s.getInputStream(), s.getOutputStream());
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        s.close();
                        server.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                Common.sleep(500);
            }
        }
    }, "tcp_server");

    /**
     * add your protocol code here
     * 
     * @param is
     * @param os
     * @throws IOException
     */
    public abstract void handleStream(InputStream is, OutputStream os) throws IOException;

    @Override
    public Thread getThread() {
        return thd;
    }
    
    public void dispose() throws Exception {
        if(thd == Thread.currentThread())
            throw new Exception("call dispose in the tcp thread will lead to dead lock!!");
        exit = true;
        while (thd.isAlive()) {
            try {
                if (server != null)
                    server.close();
                if (s != null)
                    s.close();
                thd.join(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
